[PATCH] client: disallow unprivileged users to escalate root privileges
authorXiubo Li <xiubli@redhat.com>
Wed, 3 Apr 2024 11:02:08 +0000 (19:02 +0800)
committerUtkarsh Gupta <utkarsh@debian.org>
Mon, 15 Dec 2025 12:18:10 +0000 (17:48 +0530)
An unprivileged user can `chmod 777` a directory owned by root
and gain access. Fix this bug and also add a test case for the
same.

Signed-off-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
origin: backport, https://github.com/ceph/ceph/commit/b6d85b595ea7c9e0fca10d5e77a48102110fe22c
bug-github-pull: https://github.com/ceph/ceph/pull/60314
bug: https://github.com/ceph/ceph/security/advisories/GHSA-89hm-qq33-2fjm
bug-debian: https://bugs.debian.org/1108410

Gbp-Pq: Name CVE-2025-52555-1.patch

src/client/Client.cc

index 22bd81dbb4cc170fb40c61c040e99e3fe8985db4..a4eb5054725c09507fe239075e2ca50277db2bf2 100755 (executable)
@@ -5448,7 +5448,22 @@ int Client::may_setattr(Inode *in, struct ceph_statx *stx, int mask,
   }
 
   if (mask & CEPH_SETATTR_MODE) {
-    if (perms.uid() != 0 && perms.uid() != in->uid)
+    bool allowed = false;
+    /*
+     * Currently the kernel fuse and libfuse code is buggy and
+     * won't pass the ATTR_KILL_SUID/ATTR_KILL_SGID to ceph-fuse.
+     * But will just set the ATTR_MODE and at the same time by
+     * clearing the suid/sgid bits.
+     *
+     * Only allow unprivileged users to clear S_ISUID and S_ISUID.
+     */
+    if ((in->mode & (S_ISUID | S_ISGID)) != (stx->stx_mode & (S_ISUID | S_ISGID)) &&
+        (in->mode & ~(S_ISUID | S_ISGID)) == (stx->stx_mode & ~(S_ISUID | S_ISGID))) {
+      allowed = true;
+    }
+    uint32_t m = ~stx->stx_mode & in->mode; // mode bits removed
+    ldout(cct, 20) << __func__ << " " << *in << " = " << hex << m << dec <<  dendl;
+    if (perms.uid() != 0 && perms.uid() != in->uid && !allowed)
       goto out;
 
     gid_t i_gid = (mask & CEPH_SETATTR_GID) ? stx->stx_gid : in->gid;